package cn.edu.jxau.test;

import java.util.Objects;

import cn.edu.jxau.util.Queue;

public class Main {

    public static void main(String[] args) {
        
        Cat cat1 = new Cat("cat1");
        Cat cat2 = new Cat("cat2");
        Cat cat3 = new Cat("cat3");
        Dog dog1 = new Dog("dog1");
        Dog dog2 = new Dog("dog2");
        Dog dog3 = new Dog("dog3");
        CatDogQueue queue = new CatDogQueue();
        queue.add(cat1);
        queue.add(dog1);
        queue.add(dog2);
        queue.add(dog3);
        queue.add(cat2);
        queue.add(cat3);
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
    }
}

/**
 * 猫狗队列
 * @author 付大石
 */
class CatDogQueue {
    
    private Queue<PetNode> catQueue; //存储{@code Cat}对象元素的队列
    private Queue<PetNode> dogQueue; //存储{@code Dog}对象元素的队列
    
    public CatDogQueue() {
        catQueue = new Queue<>();
        dogQueue = new Queue<>();
    }
    
    public void add(Pet pet) {
        
        PetNode node = new PetNode(pet);
        Objects.requireNonNull(pet, "参数pet不能null");
        if(pet instanceof Cat) {
            catQueue.add(node);
        } else if(pet instanceof Dog) {
            dogQueue.add(node);
        } else {
            throw new RuntimeException(String.format("type error，猫狗队对不支持该类型(%s)",pet.getClass().getName()));
        }
    }
    
    public Pet poll() {
        
        if(catQueue.isEmpty() && dogQueue.isEmpty()) { //猫狗队列都为空
            throw new RuntimeException("the queue is empty");
        } else if(catQueue.isEmpty() && !dogQueue.isEmpty()) { //猫队列为空
            return dogQueue.poll().getPet();
        } else if(!catQueue.isEmpty() && dogQueue.isEmpty()) { //狗队列为空
            return catQueue.poll().getPet();
        } else { //猫狗队列都为空
            PetNode dogNode = dogQueue.peek();
            PetNode catNode = catQueue.peek();
            if(dogNode.getEnterTime() < catNode.getEnterTime()) { //取出猫狗队列各自头结点中最早放入队列的节点
                return dogQueue.poll().getPet();
            } else {
                return catQueue.poll().getPet();
            }
        }
    }
    
    public boolean isEmpty() {
        return catQueue.isEmpty() && dogQueue.isEmpty();
    }
    
    public Dog pollDog() {
        
        if(isDogEmpty()) {
            throw new RuntimeException("dogQueue is empty");
        }
        return (Dog) dogQueue.poll().getPet();
    }
    
    public boolean isDogEmpty() {
        return dogQueue.isEmpty();
    }
    
    public Cat pollCat() {
        
        if(isCatEmpty()) {
            throw new RuntimeException("catQueue is empty");
        }
        return (Cat) catQueue.poll().getPet();
    }
    
    public boolean isCatEmpty() {
        return catQueue.isEmpty();
    }
    
    
    /**
     * 内部类，用于包装{@code Pet}对象
     * @author 付大石
     */
    private class PetNode {
        
        private Pet pet;
        private long enterTime;
        
        public PetNode(Pet pet) {
            
            this.pet = pet;
            enterTime = System.nanoTime();
        }
        
        public Class<? extends Pet> getPetClass() {
            return pet.getClass();
        }
        
        public long getEnterTime() {
            return enterTime;
        }
        
        public Pet getPet() {
            return pet;
        }
    }
}





